﻿using System;
using Csla;
using Csla.Tools;
using Csla.Validation;
using Csla.Data;
using System.Data;
using System.Linq;
using DemoCSLA.DalLinq;

namespace DemoCSLA.Libreria.Editables
{

    //******************************************
    //Clase generada por un Snippet de Erick Orlando © 2010
    //******************************************

    //Agregue aqui los using necesarios

    [Serializable()]
    public partial class FacturaCabecera : BusinessBase<FacturaCabecera>
    {
        #region Propiedades públicas


        private static PropertyInfo<string> m_IdFacturaCabecera =
            RegisterProperty<string>(c => c.IdFacturaCabecera);
        public string IdFacturaCabecera
        {
            get { return GetProperty(m_IdFacturaCabecera); }
            set { SetProperty(m_IdFacturaCabecera, value); }
        }

        private static PropertyInfo<Int32> m_Numero = RegisterProperty<Int32>(c => c.Numero, "Numero de Factura");
        public Int32 Numero
        {
            get { return GetProperty(m_Numero); }
            set { SetProperty(m_Numero, value); }
        }


        private static PropertyInfo<string> m_IdCliente = RegisterProperty<string>(c => c.IdCliente);
        public string IdCliente
        {
            get { return GetProperty(m_IdCliente); }
            set { SetProperty(m_IdCliente, value); }
        }

        private static PropertyInfo<string> m_Cliente = RegisterProperty<string>(c => c.Cliente);
        public string Cliente
        {
            get
            {
                if (!String.IsNullOrEmpty(ReadProperty(m_Nombres)))
                    SetProperty(m_Cliente, String.Format(
                         "{0} {1}", ReadProperty(m_Nombres), ReadProperty(m_Apellidos)));
                return GetProperty(m_Cliente);
            }
        }

        private static PropertyInfo<string> m_Nombres = RegisterProperty<string>(c => c.Nombres);
        public string Nombres
        {
            get { return GetProperty(m_Nombres); }
            set { SetProperty(m_Nombres, value); }
        }


        private static PropertyInfo<string> m_Apellidos = RegisterProperty<string>(c => c.Apellidos);
        public string Apellidos
        {
            get { return GetProperty(m_Apellidos); }
            set { SetProperty(m_Apellidos, value); }
        }

        private static PropertyInfo<int> m_Serie = RegisterProperty<int>(c => c.Serie);
        public int Serie
        {
            get { return GetProperty(m_Serie); }
            set { SetProperty(m_Serie, value); }
        }


        private static PropertyInfo<DateTime> m_Fecha = RegisterProperty<DateTime>(c => c.Fecha);
        public DateTime Fecha
        {
            get { return GetProperty(m_Fecha); }
            set { SetProperty(m_Fecha, value); }
        }

        private static PropertyInfo<Decimal> m_SubTotal = RegisterProperty<Decimal>(c => c.SubTotal);
        public Decimal SubTotal
        {
            get { return GetProperty(m_SubTotal); }
            set { SetProperty(m_SubTotal, value); CalculaValores(); }
        }

        private static PropertyInfo<Decimal> m_Impuestos = RegisterProperty<Decimal>(c => c.Impuestos);
        public Decimal Impuestos
        {
            get { return GetProperty(m_Impuestos); }
        }

        private static PropertyInfo<Decimal> m_Total = RegisterProperty<Decimal>(c => c.Total);
        public Decimal Total
        {
            get { return GetProperty(m_Total); }
        }

        private static PropertyInfo<FacturaDetalles> m_FacturaDetalles =
            RegisterProperty<FacturaDetalles>(d => d.FacturaDetalles);
        public FacturaDetalles FacturaDetalles
        {
            get
            {
                if (!FieldManager.FieldExists(m_FacturaDetalles))
                    LoadProperty(m_FacturaDetalles, FacturaDetalles.GetFacturaDetalles(this));
                return GetProperty(m_FacturaDetalles);
            }
        }

        private void CalculaValores()
        {
            //Calculamos el Impuesto primero
            SetProperty(m_Impuestos, ReadProperty(m_SubTotal) * Convert.ToDecimal(0.19));
            //Luego calculamos el Total
            SetProperty(m_Total, ReadProperty(m_SubTotal) + ReadProperty(m_Impuestos));
        }

        #endregion //Propiedades públicas

        #region Reglas Validación

        protected override void AddBusinessRules()
        {
            ValidationRules.AddRule(CommonRules.StringRequired, m_Cliente);
        }

        #endregion //Reglas Validación

        #region Métodos de instanciación

        private FacturaCabecera()
        {
            this.ChildChanged += new EventHandler<Csla.Core.ChildChangedEventArgs>(this.CambiaDetalle);
        }

        public static FacturaCabecera NewFacturaCabecera()
        { return DataPortal.Create<FacturaCabecera>(); }

        public static FacturaCabecera GetFacturaCabecera(String IdFacturaCabecera)
        { return DataPortal.Fetch<FacturaCabecera>(new SingleCriteria<FacturaCabecera, string>(IdFacturaCabecera)); }

        public static void DeleteFacturaCabecera(String IdFacturaCabecera)
        { DataPortal.Delete(new SingleCriteria<FacturaCabecera, String>(IdFacturaCabecera)); }

        #endregion // Métodos de instanciación

        #region Data Access

        #region Data Access - Create

        [RunLocal()]
        protected new void DataPortal_Create()
        {//Inicializar las propiedades que crea conveniente

            LoadProperty(m_IdFacturaCabecera, Guid.NewGuid().ToString());
            LoadProperty(m_Fecha, DateTime.Now);

            ValidationRules.CheckRules();
        }

        private void CambiaDetalle(Object sender, Csla.Core.ChildChangedEventArgs e)
        {
            if (FieldManager.FieldExists(m_FacturaDetalles))
                SubTotal = ReadProperty(m_FacturaDetalles).Sum(d => d.Total);
        }

        #endregion // Data Access - Create

        #region Data Access - Fetch

        private void DataPortal_Fetch(SingleCriteria<FacturaCabecera, string> criteria)
        {
            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var factura = Factura.GetFacturaById(ctx.DataContext, criteria.Value);

                LoadProperty(m_IdFacturaCabecera, factura.IdFacturaCabecera);
                LoadProperty(m_IdCliente, factura.IdCliente);
                LoadProperty(m_Numero, factura.Numero);
                LoadProperty(m_Serie, factura.Serie);
                LoadProperty(m_Fecha, factura.Fecha);
                LoadProperty(m_Nombres, factura.Cliente.Nombres);
                LoadProperty(m_Apellidos, factura.Cliente.Apellidos);
                LoadProperty(m_SubTotal, factura.SubTotal);
                LoadProperty(m_Impuestos, factura.Impuestos);
                LoadProperty(m_Total, factura.Total);

                MarkOld();
                ValidationRules.CheckRules();
            }
        }

        #endregion //Data Access - Fetch

        #region Data Access - Insert

        //[Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Insert()
        {
            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var cabecera = new Factura();
                DoInsertUpdate(cabecera);

                ctx.DataContext.Facturas.InsertOnSubmit(cabecera);

                ApplicationContext.LocalContext["padre"] = cabecera;
                
                FieldManager.UpdateChildren(this);

                ctx.DataContext.SubmitChanges(); //esto es el commit

            }
        }

        #endregion //Data Access - Insert

        #region Data Access - Update

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Update()
        {

            using (var ctx = ContextManager<DemoCSLADataContext>.GetManager(Contexto.DemoCSLA))
            {

                var obj = Factura.GetFacturaById(ctx.DataContext,
                            ReadProperty(m_IdFacturaCabecera));

                ApplicationContext.LocalContext["padre"] = obj;
                ApplicationContext.LocalContext["dpContext"] = ctx;

                if (IsSelfDirty)
                {
                    DoInsertUpdate(obj);
                }

                FieldManager.UpdateChildren(this);
                
                ctx.DataContext.SubmitChanges();

            }

        }

        #endregion //Data Access - Update

        #region DoInsertUpdate

        private void DoInsertUpdate(Factura obj)
        {
            obj.IdFacturaCabecera = ReadProperty(m_IdFacturaCabecera);
            obj.IdCliente = ReadProperty(m_IdCliente);
            obj.Numero = ReadProperty(m_Numero);
            obj.Serie = ReadProperty(m_Serie);
            obj.Fecha = ReadProperty(m_Fecha);
            obj.SubTotal = ReadProperty(m_SubTotal);
            obj.Impuestos = ReadProperty(m_Impuestos);
            obj.Total = ReadProperty(m_Total);
        }

        #endregion //DoInsertUpdate

        #region Data Access - Delete

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Delete(SingleCriteria<FacturaCabecera, string> criteria)
        {

            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var cabecera = Factura.GetFacturaById(ctx.DataContext, criteria.Value);

                //Eliminamos todos los hijos
                //de forma logica
                ctx.DataContext.Detalles.DeleteAllOnSubmit(cabecera.Detalles);
                ctx.DataContext.Facturas.DeleteOnSubmit(cabecera);
                ctx.DataContext.SubmitChanges();

            }

        }

        #endregion // Data Access - Delete

        #endregion //Data Access

    }

}
